﻿using Arction.Wpf.Charting;
using Arction.Wpf.Charting.Axes;
using Arction.Wpf.Charting.SeriesXY;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using System.Timers;
using System.Threading;
using System.Windows;
using System.Windows.Media;
using WPF自由布局.Models;
using WPF自由布局.ViewModels;
using UserControl = System.Windows.Controls.UserControl;

namespace WPF自由布局.Views
{
    public partial class BodePlotControl : UserControl,IDisposable
    {
        private LightningChartUltimate BTopChart;
        private AxisX BTopChartAxisX;
        private AxisY BTopChartAxisY;
        private bool isChartLoaded = false; // 图表加载完成标志
        private ConcurrentQueue<SensorData> dataBuffer = new ConcurrentQueue<SensorData>(); // 缓冲队列
        private System.Timers.Timer updateTimer; // 定时器

        public BodePlotControl()
        {
            InitializeComponent();

            // 初始化更新定时器
            updateTimer = new System.Timers.Timer(10); // 每秒更新一次
            updateTimer.Elapsed += OnUpdateTimerElapsed;
            updateTimer.Start();
            Loaded += (r, s) =>
            {
                Debug.WriteLine($"Loaded invoked on thread: {Thread.CurrentThread.ManagedThreadId}");
                LCPageBTopChartLoad();
                isChartLoaded = true;
                UpdateChart();
            };

            Unloaded += (r, s) =>
            {

            };
        }

        public ObservableCollection<SensorViewModel> ItemsSource
        {
            get => (ObservableCollection<SensorViewModel>)GetValue(ItemsSourceProperty);
            set
            {
                SetValue(ItemsSourceProperty, value);
                if (ItemsSource != null)
                {
                    OnItemsSourceCollectionChanged(ItemsSource, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
                    Debug.WriteLine("Manually triggered OnItemsCollectionChanged.");
                }
            }
        }

        public static readonly DependencyProperty ItemsSourceProperty =
            DependencyProperty.Register("ItemsSource", typeof(ObservableCollection<SensorViewModel>), typeof(BodePlotControl), new PropertyMetadata(null, OnItemsSourceChanged));

        private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var control = d as BodePlotControl;
            if (control == null) return;

            Debug.WriteLine("ItemsSource changed.");

            if (e.OldValue is ObservableCollection<SensorViewModel> oldCollection)
            {
                oldCollection.CollectionChanged -= control.OnItemsSourceCollectionChanged;
                Debug.WriteLine("Detached CollectionChanged event handler from old ItemsSource.");
            }
            if (e.NewValue is ObservableCollection<SensorViewModel> newCollection)
            {
                newCollection.CollectionChanged += control.OnItemsSourceCollectionChanged;
                Debug.WriteLine("Attached CollectionChanged event handler to new ItemsSource.");
            }
            // 确保标志位在图表加载后设置，并直接调用 UpdateChart
        }

        private void OnItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            Debug.WriteLine($"OnItemsSourceCollectionChanged invoked on thread: {Thread.CurrentThread.ManagedThreadId}");
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                foreach (SensorViewModel newSensor in e.NewItems)
                {
                    newSensor.DataPoints.CollectionChanged += OnDataPointsCollectionChanged;
                }
            }
            else if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                foreach (SensorViewModel oldSensor in e.OldItems)
                {
                    oldSensor.DataPoints.CollectionChanged -= OnDataPointsCollectionChanged;
                }
            }

            else if (e.Action == NotifyCollectionChangedAction.Reset)
            {
                UpdateChart();
                foreach (SensorViewModel nowSensor in ItemsSource)
                {
                    nowSensor.DataPoints.CollectionChanged += OnDataPointsCollectionChanged;
                }
            }
        }

        private void OnDataPointsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            Debug.WriteLine($"OnDataPointsCollectionChanged called on thread: {Thread.CurrentThread.ManagedThreadId}, isChartLoaded: {isChartLoaded}");

            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                foreach (SensorData newPoint in e.NewItems)
                {
                    // 将新点添加到缓冲队列中
                    dataBuffer.Enqueue(newPoint);
                }
            }
            else if (e.Action == NotifyCollectionChangedAction.Remove)
            {
                if (dataBuffer.IsEmpty || !isChartLoaded)
                    return;
                Dispatcher.Invoke(() =>
                {
                    BTopChart.BeginUpdate();
                    foreach (SensorData oldPoint in e.OldItems)
                    {
                        var series = GetOrCreateSeries(oldPoint.SensorName);
                        RemoveOldPointToSeries(oldPoint, series);
                    }
                    BTopChart.ViewXY.ZoomToFit(); // 调整视图以适应新点
                    BTopChart.EndUpdate();
                });
            }
        }

        // 定时器事件处理函数
        private void OnUpdateTimerElapsed(object sender, ElapsedEventArgs e)
        {
            if (dataBuffer.IsEmpty || !isChartLoaded)
                return;

            // 从队列中取出所有数据点
            var pointsToUpdate = new List<SensorData>();
            while (dataBuffer.TryDequeue(out SensorData point))
            {
                pointsToUpdate.Add(point);
            }

            // 更新图表
            Dispatcher.Invoke(() =>
            {
                foreach (var point in pointsToUpdate)
                {
                    var series = GetOrCreateSeries(point.SensorName);
                    AddNewPointToSeries(point, series);
                }
                BTopChart.ViewXY.ZoomToFit(); // 调整视图以适应新点
            });
        }

        private void UpdateChart()
        {
            Debug.WriteLine($"UpdateChart called on thread: {Thread.CurrentThread.ManagedThreadId}, isChartLoaded: {isChartLoaded}, BTopChart: {BTopChart}, ViewXY: {BTopChart?.ViewXY}");

            // 检查图表状态
            if (!isChartLoaded || BTopChart?.ViewXY == null || ItemsSource == null)
            {
                Debug.WriteLine("BTopChart or ViewXY is not ready in UpdateChart. Skipping update.");
                return;
            }

            Dispatcher.Invoke(() =>
            {
                BTopChart.BeginUpdate();
                foreach (var item in ItemsSource)
                {
                    var series = GetOrCreateSeries(item.SensorName);
                    series.Clear(); // 清空现有点，如果需要每次都刷新
                    foreach (var point in item.DataPoints)
                    {
                        AddNewPointToSeries(point, series);
                    }
                }
                BTopChart.ViewXY.ZoomToFit();
                BTopChart.EndUpdate();
            });
        }

        private PointLineSeries GetOrCreateSeries(string title)
        {
            var existingSeries = BTopChart.ViewXY.PointLineSeries
                .FirstOrDefault(series => series.Title.Text == title);

            if (existingSeries != null)
                return existingSeries;
            var newSeries = new PointLineSeries
            {
                Title = { Text = title, Color = Colors.Yellow },
                PointsVisible = true,
                PointStyle = { Color1 = Colors.White, Color2 = Colors.SkyBlue, Height = 5f, Width = 5f },
                LineStyle = { Width = 2f, Color = Colors.Pink },
                MouseInteraction = false
            };

            BTopChart.ViewXY.PointLineSeries.Add(newSeries);
            return newSeries;
        }

        private void AddNewPointToSeries(SensorData data, PointLineSeries series)
        {
            series.AddPoints(new[] { new SeriesPoint { Y = data.Magnitude, X = data.Speed } }, true);
        }

        private void RemoveOldPointToSeries(SensorData data, PointLineSeries series)
        {
            series.DeletePointsBeforeX(data.Speed);
        }

        private void LCPageBTopChartLoad()
        {
            BTopChart = new LightningChartUltimate();
            BTopChart.BeginUpdate();
            ConfigureChartBase();
            BTopChartAxisX = BTopChart.ViewXY.XAxes[0];
            BTopChartAxisY = BTopChart.ViewXY.YAxes[0];
            ConfigureAxis(BTopChartAxisX, BTopChartAxisY, 0, 50, 0, 100);
            BTopChart.EndUpdate();

            TopChart.Children.Add(BTopChart);      
        }

        private void ConfigureChartBase()
        {
            BTopChart.ColorTheme = ColorTheme.LightGray;
            BTopChart.Title.Text = "";
            BTopChart.Title.Color = Colors.DeepSkyBlue;
            BTopChart.Padding = new Thickness(0);
            BTopChart.Margin = new Thickness(0);
            BTopChart.ChartBackground.Color = Colors.Transparent;

            var legendBox = BTopChart.ViewXY.LegendBoxes[0];
            legendBox.Layout = LegendBoxLayout.Vertical;
            legendBox.Position = LegendBoxPositionXY.SegmentTopLeft;
            legendBox.MoveByMouse = false;
            legendBox.AllowMouseResize = false;
            legendBox.Shadow.Visible = false;
            legendBox.BorderWidth = 0;
            legendBox.Visible = false;
        }

        private void ConfigureAxis(AxisX axisX, AxisY axisY, double x1, double x2, double y1, double y2)
        {
            axisX.ScrollMode = XAxisScrollMode.None;
            axisX.ValueType = AxisValueType.Number;
            axisX.AxisColor = Colors.Black;
            axisX.Title.Text = "";
            axisX.SetRange(x1, x2);
            axisY.AxisColor = Colors.Black;
            axisY.Title.Fill.GradientColor = Colors.Black;
            axisY.SetRange(y1, y2);
            axisY.Title.Text = "";
        }

        public void Dispose()
        {
            updateTimer.Stop();
            updateTimer.Dispose();
            if (ItemsSource != null) 
            {
                ItemsSource.CollectionChanged -= OnItemsSourceCollectionChanged;
                foreach (SensorViewModel nowSensor in ItemsSource)
                {
                    nowSensor.DataPoints.CollectionChanged -= OnDataPointsCollectionChanged;
                }
            }

            BTopChart?.Dispose();
            isChartLoaded = false; // 卸载时重置标志
        }
    }
}
